﻿
Imports elpmis.variablefinder_t

Namespace variablefinder_t
    'avoid to use the instance of class, it will cost some time to be created
    'so let it be mustinherit
    Public Class t_finder(Of T)
        Implements iVariableFinder(Of T)

        Protected Delegate Function convertDelegate(ByVal var As bare_variable, ByRef o As T) As Boolean

        Private Shared Function convert(ByVal var As bare_variable, ByRef output As T) As Boolean
            Return _t(var, output)
        End Function

        Private Shared Function defaultValue() As T
            Return Nothing
        End Function

        Protected Shared Function find(ByVal ctx As context, ByVal name As String, _
                                       ByRef output As T, ByVal convert As convertDelegate) As Boolean
            Dim o As bare_variable = Nothing
            Return Not ctx Is Nothing AndAlso ctx.findVariable(name, o) AndAlso convert(o, output)
        End Function

        Protected Shared Function find(ByVal ctx As context, ByVal name As String, _
                                       ByVal convert As convertDelegate, ByVal defaultValue As T) As T
            Dim rtn As T = Nothing
            If find(ctx, name, rtn, convert) Then
                Return rtn
            Else
                Return defaultValue
            End If
        End Function

        Public Shared Function find_s(ByVal ctx As context, ByVal name As String, ByRef output As T) As Boolean
            Return find(ctx, name, output, AddressOf convert)
        End Function

        Public Shared Function find_s(ByVal ctx As context, ByVal name As String) As T
            Return find(ctx, name, AddressOf convert, defaultValue())
        End Function

        Public Overridable Function find(ByVal ctx As context, _
                                         ByVal name As String) As T Implements iVariableFinder(Of T).find
            Return ctx.findVariable(Of T)(name)
        End Function

        Public Overridable Function find(ByVal ctx As context, ByVal name As String, _
                                         ByRef output As T) As Boolean Implements iVariableFinder(Of T).find
            Return ctx.findVariable(Of T)(name, output)
        End Function
    End Class

    Public MustInherit Class variablefinder(Of T)
        Inherits t_finder(Of T)

        Protected MustOverride Function _convert(ByVal var As bare_variable, ByRef output As T) As Boolean
        Protected MustOverride Function _defaultValue() As T

        Public Overrides Function find(ByVal ctx As context, ByVal name As String, _
                                       ByRef output As T) As Boolean
            Return find(ctx, name, output, AddressOf _convert)
        End Function

        Public Overrides Function find(ByVal ctx As context, _
                                       ByVal name As String) As T
            Return find(ctx, name, AddressOf _convert, _defaultValue())
        End Function
    End Class

    Public Class bare_variable_finder_t
        Inherits variablefinder(Of bare_variable)

        Protected Overrides Function _convert(ByVal var As bare_variable, ByRef output As bare_variable) As Boolean
            Return _bare_variable(var, output)
        End Function

        Protected Overrides Function _defaultValue() As bare_variable
            Return Nothing
        End Function
    End Class

    Public Class string_finder_t
        Inherits variablefinder(Of String)

        Protected Overrides Function _convert(ByVal var As bare_variable, ByRef output As String) As Boolean
            Return _string(var, output)
        End Function

        Protected Overrides Function _defaultValue() As String
            Return Nothing
        End Function
    End Class

    Public Class int_finder_t
        Inherits variablefinder(Of Int64)

        Protected Overrides Function _convert(ByVal var As bare_variable, ByRef output As Int64) As Boolean
            Return _int(var, output)
        End Function

        Protected Overrides Function _defaultValue() As Long
            Return npos
        End Function
    End Class

    Public Class float_finder_t
        Inherits variablefinder(Of Double)

        Protected Overrides Function _convert(ByVal var As bare_variable, ByRef output As Double) As Boolean
            Return _float(var, output)
        End Function

        Protected Overrides Function _defaultValue() As Double
            Return npos
        End Function
    End Class

    Public Class bool_finder_t
        Inherits variablefinder(Of Boolean)

        Protected Overrides Function _convert(ByVal var As bare_variable, ByRef output As Boolean) As Boolean
            Return _bool(var, output)
        End Function

        Protected Overrides Function _defaultValue() As Boolean
            Return False
        End Function
    End Class
End Namespace

Public Module _variablefinder
    Private _bare_variable_finder As bare_variable_finder_t = Nothing
    Private _string_finder As string_finder_t = Nothing
    Private _int_finder As int_finder_t = Nothing
    Private _float_finder As float_finder_t = Nothing
    Private _bool_finder As bool_finder_t = Nothing

    Public Function bare_variable_finder() As bare_variable_finder_t
        Return _bare_variable_finder
    End Function

    Public Function string_finder() As string_finder_t
        Return _string_finder
    End Function

    Public Function int_finder() As int_finder_t
        Return _int_finder
    End Function

    Public Function float_finder() As float_finder_t
        Return _float_finder
    End Function

    Public Function bool_finder() As bool_finder_t
        Return _bool_finder
    End Function

    Public Class t_finder(Of T)
        Inherits variablefinder_t.t_finder(Of T)
    End Class

    Sub New()
        _bare_variable_finder = New bare_variable_finder_t()
        _string_finder = New string_finder_t()
        _int_finder = New int_finder_t()
        _float_finder = New float_finder_t()
        _bool_finder = New bool_finder_t()
    End Sub
End Module
